package en.edu.zxj.mq.mqserver.datacenter;

import en.edu.zxj.mq.MqApplication;
import en.edu.zxj.mq.mqserver.core.Binding;
import en.edu.zxj.mq.mqserver.core.Exchange;
import en.edu.zxj.mq.mqserver.core.ExchangeType;
import en.edu.zxj.mq.mqserver.core.MSGQueue;
import en.edu.zxj.mq.mqserver.mapper.MetaMapper;
import lombok.extern.slf4j.Slf4j;

import java.io.File;
import java.util.List;

/**
 * Created with IntelliJ IDEA.
 * Description：通过这个类来封装针对数据库的操作.
 *
 * @author: zxj
 * @date: 2024-02-26
 * @time: 21:21:21
 */
@Slf4j
public class DatabaseManager {
    // 由于 DataBaseManager 不是⼀个 Bean
    // 需要⼿动来获取实例
    private MetaMapper metaMapper;

    public void init() {
        metaMapper = MqApplication.context.getBean(MetaMapper.class);

        if (!checkDBExits()) {
            // 数据库不存在
            // 1. 先创建目录
            File file = new File("./data/");
            if (!file.exists()) {
                file.mkdirs();
            }
            // 2. 建表
            createTables();
            // 3. 插入默认的数据
            createDefaultData();

            log.info("创建数据库成功~");
        } else {
            log.info("数据库已经存在!");
        }
    }

    /**
     * @description: 给数据库表中, 添加默认的数据
     * 此处主要是添加一个默认的交换机
     * RabbitMQ 里有一个这样的设定: 带有一个 匿名 的交换机, 类型是 DIRECT
     **/
    private void createDefaultData() {
        // 构造一个默认的交换机
        Exchange exchange = new Exchange();
        exchange.setName("");
        exchange.setType(ExchangeType.DIRECT);
        exchange.setDurable(false);
        exchange.setAutoDelete(false);
        metaMapper.insertExchange(exchange);

        log.info("创建默认的数据成功~");
    }

    private boolean checkDBExits() {
        File file = new File("./data/meta.db");
        return file.exists();
    }

    /**
     * 这个方法用来建表.
     * 建库操作并不需要手动执行. (不需要手动创建 meta.db 文件)
     * 首次执行这里的数据库操作的时候, 就会自动的创建出 meta.db 文件来 (MyBatis 帮我们完成的)
     **/
    private void createTables() {
        metaMapper.createMSGQueueTable();
        metaMapper.createBindingTable();
        metaMapper.createExchangeTable();

        log.info("建表成功");
    }

    // 封装其他的数据库操作
    Integer insertExchange(Exchange exchange) {
        return metaMapper.insertExchange(exchange);
    }

    Integer deleteExchangeByName(String name) {
        return metaMapper.deleteExchangeByName(name);
    }

    List<Exchange> selectAllExchanges() {
        return metaMapper.selectAllExchanges();
    }

    Integer insertMSGQueue(MSGQueue msgQueue) {
        return metaMapper.insertMSGQueue(msgQueue);
    }

    Integer deleteMSGQueueByName(String name) {
        return metaMapper.deleteMSGQueueByName(name);
    }

    List<MSGQueue> selectAllMSGQueues() {
        return metaMapper.selectAllMSGQueues();
    }


    Integer insertBinding(Binding binding) {
        return metaMapper.insertBinding(binding);
    }

    Integer deleteBinding(String exchangeName, String queueName) {
        return metaMapper.deleteBinding(exchangeName, queueName);
    }

    List<Binding> selectAllBindings() {
        return metaMapper.selectAllBindings();
    }

    // 清理资源
    public void deleteDB() {
        File file = new File("./data/meta.db");
        if (file.delete()) {
            log.info("删除数据库文件成功~");
        } else {
            log.info("删除数据库文件失败~");
        }

        File dataDir = new File("./data/");
        // 使用 delete 删除目录的时候, 需要保证目录是空的.
        if (dataDir.delete()) {
            log.info("删除数据库目录成功~");
        } else {
            log.info("删除数据库目录失败~");
        }
    }
}
